/**
 * Copyright 2009 University of  Washington
 * This code is released under the GPL version 3 - with a copy of the license included
 * @author Maya Hao Li
 *
 */
package seedpod.webapp.view.servlet;


import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Iterator;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import seedpod.kb2db.ClsMap;
import seedpod.kb2db.SlotMap;
import seedpod.model.rdb.MetaRdbCls;
import seedpod.model.rdb.MetaRdbSlot;
import seedpod.util.XMLWriter;
import seedpod.util.XMLWriter.XMLException;
import seedpod.webapp.Seedpod;
import seedpod.webapp.view.htmlwidget.Table;
import seedpod.webapp.view.htmlwidget.TableRow;

public class ClsViewer extends HttpServlet {

	private static final long serialVersionUID = 1911245011233923015L;

	private static StringBuffer getAtt( String name, String val ) {
		return new StringBuffer( name + ": " + val + "<br>" );
	}

	public String renderClsInfo( ClsMap cmap ) {
		StringBuffer box = new StringBuffer();
		box.append( getAtt( MetaRdbCls.NAME, cmap.getName() ) );
		box.append( getAtt( "MetaCls", cmap.getClsType() ) );
		box.append( getAtt( "Concrete", Boolean.toString( cmap.isConcrete() ) ) );
		box.append( getAtt( "inLine", Boolean.toString( cmap.isInline() ) ) ) ;

		return box.toString();
	}

	public static String renderClsBox( ClsMap cmap ) {

		Table clsTable = new Table( "ClsMapBox" );
		clsTable.setCssClass( "boxTable" );
		clsTable.setAlternativeRowColor( false );
		clsTable.setTableCellSpacing( 1, 2 );

		clsTable.addRow();
		clsTable.addCell( MetaRdbCls.FRAME_ID ).setIsHeader( true );
		clsTable.addCell( cmap.getFrameId() );

		clsTable.addRow();
		clsTable.addCell( MetaRdbCls.NAME ).setIsHeader( true );
		clsTable.addCell( cmap.getName() );

		// MetaRdbCls.METACLSNAME
		clsTable.addRow();
		clsTable.addCell( "Meta Class" ).setIsHeader( true );
		clsTable.addCell( cmap.getClsType() );

		clsTable.addRow();
		clsTable.addCell( MetaRdbCls.IS_CONCRETE ).setIsHeader( true );
		clsTable.addCell( cmap.isConcrete() );

		clsTable.addRow();
		clsTable.addCell( MetaRdbCls.INLINE ).setIsHeader( true );
		clsTable.addCell( cmap.isInline() );

		return clsTable.render();
	}

	public static String listSlots( ClsMap cmap ) {
		Collection<SlotMap> slotMaps = cmap.getSlotMaps();
		Iterator<SlotMap> mapItr = slotMaps.iterator();
		Table slotTable = new Table( "slotMapTable" );
		slotTable.setTableCellSpacing( 1, 10 );
		slotTable.setCssClass( "generic" );
		slotTable.setOnMouseOverClass( "onMouseOver" );
		slotTable.setAlternativeRowCssClass( "odd", "even" );
		slotTable.setAlternativeRowColor( true );

		TableRow header = slotTable.addRow();
		header.setIsHeader( true );
		header.setCssClass( "header" );
		slotTable.addCell( MetaRdbSlot.NAME );
		slotTable.addCell( MetaRdbCls.FRAME_ID );

		while (mapItr.hasNext()) {
			SlotMap smap = mapItr.next();
			slotTable.addRow();
			slotTable.addCell( smap.getName() );
			slotTable.addCell( smap.getFrameId() );
		}
		return slotTable.render();
	}

	public static String renderClsTable( ClsMap cmap ) {
		Table clsTable = new Table( "ClsMapTable" );
		clsTable.setTableCellSpacing( 1, 10 );
		clsTable.setBorder( 0 );
		clsTable.setCssClass( "generic" );
		clsTable.setOnMouseOverClass( "onMouseOver" );
		clsTable.setAlternativeRowCssClass( "odd", "even" );
		clsTable.setAlternativeRowColor( true );

		TableRow header = clsTable.addRow();
		header.setCssClass( "header" );
		header.setIsHeader( true );
		header.addCell( MetaRdbCls.FRAME_ID );
		header.addCell( MetaRdbCls.NAME );
		header.addCell( MetaRdbCls.IS_CONCRETE );
		header.addCell( MetaRdbCls.INLINE );
		header.addCell( MetaRdbCls.METACLSNAME );
		header.addCell( MetaRdbCls.BROWSER_PATTERN );
		header.addCell( MetaRdbCls.PARENT );
		header.addCell( MetaRdbCls.PRIMARY_KEY );
		header.addCell( MetaRdbCls.TABLE_NAME );
		header.addCell( MetaRdbCls.CLS_TYPE );
		header.addCell( MetaRdbCls.USER_DEFINED_NAME );
		header.addCell( MetaRdbCls.VIEW_NAME );

		TableRow data = clsTable.addRow();
		data.addCell( cmap.getFrameId() );
		data.addCell( cmap.getName() );
		data.addCell( cmap.isConcrete() );
		data.addCell( cmap.isInline() );
		data.addCell( cmap.getClsType() );
		data.addCell( cmap.getBrowserPattern() );
		data.addCell( cmap.getParentClsName() );
		data.addCell( cmap.getPrimaryKey() );
		data.addCell( cmap.getRelationName() );
		data.addCell( cmap.getClsType() );
		data.addCell( cmap.getUserDefinedName() );
		data.addCell( cmap.getViewName() );

		return clsTable.render();
	}

	public static XMLWriter toXML( ClsMap cmap ) {
		XMLWriter wrt = new XMLWriter( "ClsMap" );

		try {
			wrt.addElement( MetaRdbCls.FRAME_ID, cmap.getFrameId() );
			wrt.addElement( MetaRdbCls.NAME, cmap.getName() );
			wrt.addElement( MetaRdbCls.IS_CONCRETE, cmap.isConcrete() );
		}
		catch (XMLException e) {
			wrt = new XMLWriter( "XMLException: " + e.getMessage() );
			e.printStackTrace();
		}
		return wrt;
	}

	public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException {
		PrintWriter out;
		ClsMap cmap;
		String clsName = (String)request.getParameter( "clsName" );

		try {
			out = response.getWriter();
			if ( clsName == null || clsName.length() == 0 ) {
				out.write( "What's name of the Cls you are looking for?" );
				return;
			}

			cmap = Seedpod.getModelMap().getClsMap( clsName );
			if ( cmap == null ) {
				out.write( "I don't know class with name " + clsName );
				return;
			}

			response.setContentType( "text/html" );
			out.write( renderClsInfo( cmap ) );
		}
		catch (IOException e1) {
			e1.printStackTrace();
		}
	}

	public void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
		doGet( request, response );
	}

	public static int getHeaderHTML() {
		// TODO Auto-generated method stub
		return 0;
	}

}
